/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package xsystems.propagationModel;

import java.lang.Math;
import java.text.DecimalFormat;
import java.util.ArrayList;

/**
 *
 * @author Karine
 */
public class TwoRaysModel extends PropagationModel {

    private String nomeMetodo;
    private double distTotal;
    private boolean calculePot_Recebida = false;
    private float Pt;
    private float Gt;
    private float Gr;
    private float Ht;
    private float Hr;
    private int numberPoints;
    private ArrayList<Point> Points_TwoRaysModel;

    //Para a potencia pathloss
    public TwoRaysModel(String nomeMetodo, int distTotal, float Gt, float Gr, float Ht, float Hr, int numberPoints) {

        super(nomeMetodo);
        this.calculePot_Recebida = false;
        this.nomeMetodo = nomeMetodo; //Nome do Método
        this.distTotal = distTotal; //Distância Total percorrida
        this.Gt = Gt; // Ganho no transmissor
        this.Gr = Gr; // Ganho no Receptor
        this.Ht = Ht; //Altura do Transmissor
        this.Hr = Hr; // Altura do Receptor
        this.numberPoints = numberPoints; // Número de pontos considerados nas medições
        Points_TwoRaysModel = new ArrayList<>();

    }

    //Para a potencia recebida
    public TwoRaysModel(String nomeMetodo, int distTotal, float Pt, float Gt, float Gr, float Ht, float Hr, int numberPoints) {

        super(nomeMetodo);
        this.nomeMetodo = nomeMetodo; //Nome do Método
        this.calculePot_Recebida = true;
        this.distTotal = distTotal; //Distância Total percorrida
        this.Pt = Pt;
        this.Gt = Gt; // Ganho no transmissor
        this.Gr = Gr; // Ganho no Receptor
        this.Ht = Ht; //Altura do Transmissor
        this.Hr = Hr; // Altura do Receptor
        this.numberPoints = numberPoints; // Número de pontos considerados nas medições
        Points_TwoRaysModel = new ArrayList<>();
    }

    // Método que calcula atenuação do sinal ao longo da distância
    public ArrayList<Point> getPathLoss() {

        double[] attenuation = new double[numberPoints + 1]; //Cria um vetor para armazenar o valor encontrado de atenuação em cada ponto
        double rate = distTotal / numberPoints; //rate é a lagura de um intervalo ou a razão  

        //desconsidera o ponto i = 0
        for (int i = 1; i < numberPoints + 1; i++) {
            double positionReceiver = i * rate; // retorna a posição do receptor em um dado instante
            //Calculo da atenuação em um ponto específico:
            attenuation[i] = (double) ((40 * Math.log10(positionReceiver)) - (10 * Math.log10(Gt) + 10 * Math.log10(Gr) + 20 * Math.log10(Ht) + 20 * Math.log10(Hr)));
            //perda = 40*log10(distancia(k))-(10*log10(Gt)+10*log10(Gr)+20*log10(ht)+20*log10(hr));           

            // Criando um objeto do tipo ponto e adiciona na lista de Pontos:
            Point ponto = new Point(positionReceiver, attenuation[i]);
            Points_TwoRaysModel.add(ponto);
        }
        return Points_TwoRaysModel;
    }

    // Método que calcula a potência recebida do sinal ao longo da distância
    public ArrayList<Point> getReceivedPower() {

        double[] Pr = new double[numberPoints + 1]; //Cria um vetor para armazenar o valor encontrado de atenuação em cada ponto
        double rate = distTotal / numberPoints; //rate é a lagura de um intervalo ou a razão  

        //desconsidera o ponto i = 0
        for (int i = 10; i < numberPoints + 1; i++) {
            double positionReceiver = i * rate; // retorna a posição do receptor em um dado instante
            //Calculo da potência em um ponto específico:          
            
            Pr[i] = (double) 10*Math.log10(((Pt *Gt * Gr * (Math.pow(Ht, 2)) * (Math.pow(Hr, 2))) / Math.pow(positionReceiver,4)));
            //Pr = (Pt*Gt*Gr*(ht^2)*(hr^2))/((distancia(k)*1000)^4);           

            // Criando um objeto do tipo ponto e adiciona na lista de Pontos:
            Point ponto = new Point(positionReceiver, Pr[i]);
            // System.out.println(positionReceiver + " " + Pr[i]);
            Points_TwoRaysModel.add(ponto);
        }
        return Points_TwoRaysModel;
    }

    @Override
    public ArrayList<Point> getPoints() {

        if (calculePot_Recebida == true) {
            return getReceivedPower();
        } else {
            return getPathLoss();
        }
    }

    /*@Override
     public ArrayList<Point> getPoints() {

     return getPathLoss();

     }*/
}
